import MIPS.Mips;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.omg.CORBA.PRIVATE_MEMBER;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;

public class AnalyseIR {
    private Stack<SymbolTable> tables;
    private ArrayList<Quaternion> IRs;
    private Stack<Pairs> calculation;
    private HashMap<String, Boolean> map = new HashMap<String, Boolean>();  //临时存储
    private static int index = 8;
    private Boolean noBranch = true;
    private static int branch_index = 0;
    private static int while_index = 0;
    private static int block_index = 0;
    private Boolean isIF = false;
    private Boolean isWhile = false;
    private Boolean isAnd = false;
    private Boolean isOr = false;
    private Stack<Quaternion> branches = new Stack<>();

    public AnalyseIR() {
        this.tables = new Stack<>();
        this.IRs = new ArrayList<>();
        this.calculation = new Stack<>();
    }

    public void initMap() {
        for (int i = 8; i <= 25; i++) {
            this.map.put("&" + i, false);
        }
    }

    public String useMap() {
        map.put("&" + index, true);
        String str = "&" + index;
        /*if (index == 25) {
            index = 8;
        } else {
            index++;
        }*/
        index++;
        return str;
    }

    public ArrayList<Quaternion> getIRs() {
        return this.IRs;
    }

    public Quaternion.OP kindToOp(Pairs.Kind kind) {
        Quaternion.OP result;
        switch (kind) {
            case MINU:
                result = Quaternion.OP.SUB;
                break;
            case PLUS:
                result = Quaternion.OP.ADD;
                break;
            case MULT:
                result = Quaternion.OP.MULT;
                break;
            case DIV:
                result = Quaternion.OP.DIV;
                break;
            case MOD:
                result = Quaternion.OP.MOD;
                break;
            default:
                result = null;
        }
        return result;
    }

    public Pairs containsIdent(String token) {
        Pairs result = null;
        for (SymbolTable i : tables) {
            if (i.tableMap.containsKey(token)) {
                result = i.tableMap.get(token);
            }
        }
        return result;
    }

    public Pairs buildIR(Node node) {
        int global_begin = 0;
        int global_end = 0;
        if (node.getPair().getLine() == 38) {
            int flag = 1;
        }
        if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("CompUnit")) {
            SymbolTable table = new SymbolTable();
            tables.push(table);
        }
        if (node.getChildren() != null) {
            for (Node i : node.getChildren()) {
                if (!i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                    if (i.getPair().getKind().equals(Pairs.Kind.BREAKTK) || i.getPair().getKind().equals(Pairs.Kind.CONTINUETK)) {
                        /*if (i.getPair().getKind().equals(Pairs.Kind.BREAKTK)) {
                            BranchJump go = new BranchJump(Quaternion.OP.GOTO, "end", while_index - 1, "while");
                            IRs.add(go);
                        } else {
                            BranchJump go = new BranchJump(Quaternion.OP.GOTO, "begin", while_index - 1, "while");
                            IRs.add(go);
                        }*/
                    } /*else if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("Block") && i.getPair().getKind().equals(Pairs.Kind.RBRACE)) {
                        tables.pop();
                    }*/
                } else {
                    if (i.getPair().getToken().equals("Decl")) {
                        if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("CompUnit") && global_begin == 0) {
                            Label label = new Label(i.getPair(), "begin", "global");
                            IRs.add(label);
                            global_begin = 1;
                        }
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("FuncDef")) {
                        if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("CompUnit") && global_end == 0 && global_begin == 1) {
                            Label label = new Label(i.getPair(), "end", "global");
                            IRs.add(label);
                            global_end = 1;
                        }
                        if (i.getPair().getLine() == 11) {
                            int flag = 1;
                        }
                        insertTableFunc(i);
                    } else if (i.getPair().getToken().equals("ConstDecl")) {
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("ConstDef")) {
                        if (i.getPair().getLine() == 73) {
                            int flag = 1;
                        }
                        insertTableVal(i);
                        //buildIR(i);
                    } else if (i.getPair().getToken().equals("ConstInitVal")) {
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("VarDecl")) {
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("VarDef")) {
                        insertTableVar(i);
                    } else if (i.getPair().getToken().equals("InitVal")) {
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("MainFuncDef")) {
                        if (node.getPair().getKind().equals(Pairs.Kind.PARSE) && node.getPair().getToken().equals("CompUnit") && global_end == 0 && global_begin == 1) {
                            Label label = new Label(i.getPair(), "end", "global");
                            IRs.add(label);
                            global_end = 1;
                        }
                        Pairs pairs = new Pairs(Pairs.Kind.FUNC, i.getChildren().get(1).getPair().getToken(), "int", i.getChildren().get(1).getPair().getLine());
                        Label label = new Label(pairs, "begin", "main");
                        IRs.add(label);
                        if (tables.peek().tableMap.containsKey(pairs.getToken())) {

                        }
                        tables.peek().addPair(pairs);
                        for (Node j : i.getChildren()) {
                            if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Block")) {
                                int index = block_index;
                                block_index++;
                                Label label1 = new Label("begin", index, "block");
                                IRs.add(label1);
                                SymbolTable table = new SymbolTable();
                                table.setType("int");
                                tables.push(table);
                                buildIR(j);
                                if (j.getChildren().size() > 2) {
                                    if (!j.getChildren().get(j.getChildren().size() - 2).getChildren().get(0).getChildren().get(0).getPair().getKind().equals(Pairs.Kind.RETURNTK)) {

                                    }
                                } else if (j.getChildren().size() == 2) {

                                }
                                tables.pop();
                                Label label2 = new Label("end", index, "block");
                                IRs.add(label2);
                            }
                        }
                        Label label1 = new Label(pairs, "end", "main");
                        IRs.add(label1);
                        //buildIR(i);
                    } else if (i.getPair().getToken().equals("Block")) {
                        if (i.getPair().getLine() == 354) {
                            int falg = 1;
                        }
                        SymbolTable table = new SymbolTable();
                        if (tables.peek().isCircle() || tables.peek().isInt() || tables.peek().isVoid()) {
                            table.setType(tables.peek().getType());
                        }
                        table.setWhileIndex(tables.peek().getWhileIndex());
                        int index = block_index;
                        block_index++;
                        Label label1 = new Label("begin", index, "block");
                        IRs.add(label1);
                        tables.push(table);
                        buildIR(i);
                        tables.pop();
                        Label label2 = new Label("end", index, "block");
                        IRs.add(label2);
                    } else if (i.getPair().getToken().equals("BlockItem")) {
                        if (i.getPair().getLine() == 133) {
                            int flag = 1;
                        }
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("Stmt")) {
                        buildTableStmt(i);
                        //buildIR(i);
                    } else if (i.getPair().getToken().equals("LVal")) {
                        processLVal(i);
                    } else if (i.getPair().getToken().equals("Cond")) {
                        buildIR(i);
                    } else if (i.getPair().getToken().equals("Exp")) {
                        buildTableExp(i);
                    } else if (i.getPair().getToken().equals("ConstExp")) {
                        buildTableExp(i.getChildren().get(0));
                    }
                }
            }
        }
        return null;
    }

    public void insertTableFunc(Node node) {
        Pairs pairs = new Pairs(Pairs.Kind.FUNC, node.getChildren().get(1).getPair().getToken(), node.getChildren().get(1).getPair().getLine());
        if (pairs.getLine() == 130) {
            int flag = 1;
        }
        ArrayList<Pairs> paramList = new ArrayList<>();
        tables.peek().addPair(pairs);
        Label label = new Label(pairs, "begin", "func");
        IRs.add(label);
        FuncDefine define = new FuncDefine(pairs, null, 0);
        IRs.add(define);
        SymbolTable table = new SymbolTable();
        tables.push(table);
        if (tables.peek().isCircle() || tables.peek().isInt() || tables.peek().isVoid()) {
            table.setType(tables.peek().getType());
        }
        for (Node i : node.getChildren()) {
            if (i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                if (i.getPair().getToken().equals("FuncType")) {
                    Node j = i.getChildren().get(0);
                    if (j.getPair().getKind().equals(Pairs.Kind.INTTK)) {
                        pairs.setType("int");
                        tables.peek().setType("int");
                    } else {
                        pairs.setType("void");
                        tables.peek().setType("void");
                    }
                } else if (i.getPair().getToken().equals("FuncFParams")) {
                    if (i.getPair().getLine() == 130) {
                        int flag = 1;
                    }
                    for (Node j : i.getChildren()) {
                        if (j.getPair().getToken().equals("FuncFParam")) {
                            if (j.getChildren().size() > 4) {
                                buildIR(j);
                                Pairs param = new Pairs(Pairs.Kind.ARRAY_VAR, j.getChildren().get(1).getPair().getToken(), "int", j.getChildren().get(1).getPair().getLine(), 2);
                                tables.peek().addPair(param);
                                paramList.add(param);
                                ArrayList<Pairs> list = new ArrayList<>();
                                list.add(calculation.pop());
                                param.setParams(list);
                                FuncDefine define1 = new FuncDefine(pairs, param, 1);
                                IRs.add(define1);
                            } else if (j.getChildren().size() == 2) {
                                Pairs param = new Pairs(Pairs.Kind.VAR, j.getChildren().get(1).getPair().getToken(), "int", j.getChildren().get(1).getPair().getLine());
                                tables.peek().addPair(param);
                                paramList.add(param);
                                FuncDefine define1 = new FuncDefine(pairs, param, 1);
                                IRs.add(define1);
                            } else {
                                Pairs param = new Pairs(Pairs.Kind.ARRAY_VAR, j.getChildren().get(1).getPair().getToken(), "int", j.getChildren().get(1).getPair().getLine(), 1);
                                tables.peek().addPair(param);
                                paramList.add(param);
                                FuncDefine define1 = new FuncDefine(pairs, param, 1);
                                IRs.add(define1);
                            }
                        }
                    }
                } else if (i.getPair().getToken().equals("Block")) {
                    pairs.setParams(paramList);
                    if (i.getPair().getLine() == 130) {
                        int flag = 1;
                    }
                    buildIR(i);
                    if (i.getPair().getLine() == 354) {
                        int flag = 1;
                    }
                    tables.pop();
                }
            }
        }
        int flag = 1;
        Label label1 = new Label(pairs, "end", "func");
        IRs.add(label1);
    }

    public void insertTableVal(Node node) {
        Pairs pairs = new Pairs(Pairs.Kind.VAL, node.getChildren().get(0).getPair().getToken(), "int", node.getChildren().get(0).getPair().getLine());
        if (pairs.getLine() == 133) {
            int flag = 1;
        }
        Quaternion.OP op = Quaternion.OP.DEF;
        int type = 0;
        tables.peek().addPair(pairs);
        Pairs dim1 = null;
        Pairs dim2 = null;
        Define define = null;
        for (Node i : node.getChildren()) {
            if (!i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                if (i.getPair().getKind().equals(Pairs.Kind.LBRACK)) {
                    pairs.setKind(Pairs.Kind.ARRAY_VAL);
                    pairs.setDim(pairs.getDim() + 1);
                } else if (i.getPair().getKind().equals(Pairs.Kind.ASSIGN)) {
                    if (pairs.getKind().equals(Pairs.Kind.ARRAY_VAR) || pairs.getKind().equals(Pairs.Kind.ARRAY_VAL)) {
                        op = Quaternion.OP.ARRAY;
                    } else if (pairs.getKind().equals(Pairs.Kind.VAL)) {
                        op = Quaternion.OP.VAL;
                        type = 1;
                    } else if (pairs.getKind().equals(Pairs.Kind.VAR)) {
                        op = Quaternion.OP.VAR;
                        type = 1;
                    }
                    define = new Define(pairs, dim1, dim2, null, type, op);
                    ArrayList<Pairs> dims = new ArrayList<>();
                    if (dim1 != null) {
                        dims.add(dim1);
                    }
                    if (dim2 != null) {
                        dims.add(dim2);
                    }
                    pairs.setParams(dims);
                    if (dim1 != null) {
                        IRs.add(define);
                    }
                }
            } else {
                if (i.getPair().getToken().equals("ConstExp")) {
                    buildTableExp(i);
                    if (pairs.getDim() == 1) {
                        dim1 = calculation.pop();
                    } else if (pairs.getDim() == 2) {
                        dim2 = calculation.pop();
                    } else {
                        Pairs temp = calculation.pop();
                        if (temp.getInit()) {
                            pairs.setValue(temp.getValue());
                        }
                    }
                } else if (i.getPair().getToken().equals("ConstInitVal")) {
                    ArrayList<Pairs> oldList = new ArrayList<Pairs>(calculation);
                    buildIR(i);
                    ArrayList<Pairs> newList = new ArrayList<Pairs>(calculation);
                    newList.removeAll(oldList);
                    int index1 = 0;
                    for (Pairs j : newList) {
                        if (pairs.getDim() == 0) {
                            define.solveAnswer(j);
                            define.getPair_a().setValue(define.getAnswer().getValue());
                            calculation.remove(j);
                        } else {
                            // TODO: 数组
                            Pairs address = new Pairs(Pairs.Kind.VAL, Integer.toString(index1));
                            address.setValue(index1);
                            Assign assign = new Assign(pairs, address, j, Quaternion.OP.ARRAY);
                            IRs.add(assign);
                            calculation.remove(j);
                            pairs.values.add(j.getValue());
                        }
                        index1++;
                    }
                }
            }
        }
        tables.peek().addPair(pairs);
        if (dim1 == null) {
            IRs.add(define);
        }
    }

    public void insertTableVar(Node node) {
        Pairs pairs = new Pairs(Pairs.Kind.VAR, node.getChildren().get(0).getPair().getToken(), "int", node.getChildren().get(0).getPair().getLine());
        if (pairs.getLine() == 12) {
            int flag = 1;
        }
        Quaternion.OP op = Quaternion.OP.DEF;
        int type = 0;
        tables.peek().addPair(pairs);
        int init = 0;
        int defined = 0;
        Pairs dim1 = null;
        Pairs dim2 = null;
        Define define = null;
        for (Node i : node.getChildren()) {
            if (!i.getPair().getKind().equals(Pairs.Kind.PARSE)) {
                if (i.getPair().getKind().equals(Pairs.Kind.LBRACK)) {
                    pairs.setKind(Pairs.Kind.ARRAY_VAR);
                    pairs.setDim(pairs.getDim() + 1);
                } else if (i.getPair().getKind().equals(Pairs.Kind.ASSIGN)) {
                    if (pairs.getKind().equals(Pairs.Kind.ARRAY_VAR) || pairs.getKind().equals(Pairs.Kind.ARRAY_VAL)) {
                        op = Quaternion.OP.ARRAY;
                    } else if (pairs.getKind().equals(Pairs.Kind.VAL)) {
                        op = Quaternion.OP.VAL;
                        type = 1;
                    } else if (pairs.getKind().equals(Pairs.Kind.VAR)) {
                        op = Quaternion.OP.VAR;
                        type = 1;
                    }
                    define = new Define(pairs, dim1, dim2, null, type, op);
                    ArrayList<Pairs> dims = new ArrayList<>();
                    if (dim1 != null) {
                        dims.add(dim1);
                    }
                    if (dim2 != null) {
                        dims.add(dim2);
                    }
                    pairs.setParams(dims);
                    if (dim1 != null) {
                        defined = 1;
                        IRs.add(define);
                    }
                }
            } else {
                if (i.getPair().getToken().equals("ConstExp")) {
                    buildTableExp(i);
                    if (pairs.getDim() == 1) {
                        dim1 = calculation.pop();
                        if (dim1.getKind().equals(Pairs.Kind.ARRAY_VAR) || dim1.getKind().equals(Pairs.Kind.ARRAY_VAL)) {
                            dim1.setValue(containsIdent(dim1.getToken()).values.get(dim1.getParams().get(0).getValue()));
                        }
                    } else if (pairs.getDim() == 2) {
                        dim2 = calculation.pop();
                        if (dim2.getKind().equals(Pairs.Kind.ARRAY_VAR) || dim2.getKind().equals(Pairs.Kind.ARRAY_VAL)) {
                            dim2.setValue(containsIdent(dim2.getToken()).values.get(dim2.getParams().get(0).getValue()));
                        }
                    } else {
                        Pairs temp = calculation.pop();
                        if (temp.getInit()) {
                            pairs.setValue(temp.getValue());
                        }
                    }
                } else if (i.getPair().getToken().equals("InitVal")) {
                    init = 1;
                    if (pairs.getLine() == 5) {
                        int flag = 1;
                    }
                    ArrayList<Pairs> oldList = new ArrayList<Pairs>(calculation);
                    buildIR(i);
                    ArrayList<Pairs> newList = new ArrayList<Pairs>(calculation);
                    newList.removeAll(oldList);
                    int index1 = 0;
                    for (Pairs j : newList) {
                        if (pairs.getDim() == 0) {
                            if (j.getInit()) {
                                define.solveAnswer(j);
                                define.getPair_a().setValue(define.getAnswer().getValue());
                            } else {
                                define.solveAnswer(j);
                            }
                            calculation.remove(j);
                        } else {
                            // TODO: 数组
                            Pairs address = new Pairs(Pairs.Kind.VAL, Integer.toString(index1));
                            address.setValue(index1);
                            Pairs address2 = null;
                            if (!j.getParams().isEmpty()) {
                                address2 = j.getParams().get(0);
                            }
                            Assign assign = new Assign(pairs, address, j, address2, Quaternion.OP.ARRAY);
                            IRs.add(assign);
                            pairs.values.add(j.getValue());
                            /*Define define1 = new Define(pairs, null, null, j, 1,op);
                            define1.setIndex(index1);
                            IRs.add(define1);*/
                            calculation.remove(j);
                        }
                        index1++;
                    }
                }
            }
        }
        if (init == 0) {
            define = new Define(pairs, dim1, dim2, null, type, Quaternion.OP.VAR);
            ArrayList<Pairs> dims = new ArrayList<>();
            if (dim1 != null) {
                dims.add(dim1);
            }
            if (dim1 == null) {
                IRs.add(define);
            } else {
                if (dim2 != null) {
                    dims.add(dim2);
                }
                pairs.setParams(dims);
                IRs.add(define);
            }
            int flag = 1;
            if (tables.size() == 1) {
                if (dim2 != null) {
                    for (int i = 0; i < dim1.getValue() * dim2.getValue(); i++) {
                        Pairs address = new Pairs(Pairs.Kind.VAL, Integer.toString(i));
                        address.setValue(i);
                        Pairs address2 = null;
                        Pairs zero = new Pairs(Pairs.Kind.NUM, "0");
                        Assign assign = new Assign(pairs, address, zero, address2, Quaternion.OP.ARRAY);
                        IRs.add(assign);
                        pairs.values.add(0);
                    }
                } else if (dim1 != null) {
                    for (int i = 0; i < dim1.getValue(); i++) {
                        Pairs address = new Pairs(Pairs.Kind.VAL, Integer.toString(i));
                        address.setValue(i);
                        Pairs address2 = null;
                        Pairs zero = new Pairs(Pairs.Kind.NUM, "0");
                        Assign assign = new Assign(pairs, address, zero, address2, Quaternion.OP.ARRAY);
                        IRs.add(assign);
                        pairs.values.add(0);
                    }
                }
            }
        } else {
            if (defined == 0) {
                IRs.add(define);
            }
        }
    }

    public Pairs processLVal(Node node) {
        Pairs pairs = null;
        Pairs first = null;
        Pairs temp = null;
        int array = 0;
        if (node.getPair().getLine() == 33) {
            int flag = 1;
        }
        int dim = 0;
        ArrayList<Pairs> list = new ArrayList<>();
        for (Node j : node.getChildren()) {
            if (j.getPair().getKind().equals(Pairs.Kind.IDENFR)) {
                temp = containsIdent(j.getPair().getToken());
                first = new Pairs(temp.getKind(), temp.getToken(), temp.getType(), temp.getLine(), temp.getDim());
                if (!(temp.getKind().equals(Pairs.Kind.ARRAY_VAR) || temp.getKind().equals(Pairs.Kind.ARRAY_VAL)) && temp.getInit()) {
                    first.setValue(temp.getValue());
                }
                pairs = first;
                pairs.setParams(temp.getParams());
                if (pairs.getParams().size() == 2) {
                    int flag = 1;
                }
                dim = temp.getDim();
                // TODO: 数组
            } else if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Exp")) {
                array = 1;
                ArrayList<Pairs> tempStack = new ArrayList<>();
                while (calculation.size() != 0) {
                    tempStack.add(calculation.pop());
                }
                buildTableExp(j);
                Pairs result = calculation.pop();
                while (tempStack.size() != 0) {
                    Pairs end = tempStack.get(tempStack.size() - 1);
                    calculation.push(end);
                    tempStack.remove(end);
                }
                calculation.push(result);
                if (dim == 1) {
                    if (pairs.getParams().size() == 1) {
                        Pairs dim1;
                        if (!pairs.getParams().get(0).getKind().equals(Pairs.Kind.NUM)) {
                            dim1 = new Pairs(Pairs.Kind.NUM, Integer.toString(pairs.getParams().get(0).getValue()));
                            dim1.setValue(pairs.getParams().get(0).getValue());
                        } else {
                            dim1 = pairs.getParams().get(0);
                        }
                        Expression expression = new Expression(calculation.pop(), dim1, Quaternion.OP.MULT);
                        expression.solveAnswer(index);
                        index++;
                        IRs.add(expression);
                        calculation.push(expression.getAnswer());
                    } else {
                        Pairs dim2;
                        if (!pairs.getParams().get(1).getKind().equals(Pairs.Kind.NUM)) {
                            dim2 = new Pairs(Pairs.Kind.NUM, Integer.toString(pairs.getParams().get(1).getValue()));
                            dim2.setValue(pairs.getParams().get(1).getValue());
                        } else {
                            dim2 = pairs.getParams().get(1);
                        }
                        Expression expression = new Expression(calculation.pop(), dim2, Quaternion.OP.MULT);
                        expression.solveAnswer(index);
                        index++;
                        IRs.add(expression);
                        calculation.push(expression.getAnswer());
                    }
                } else if (dim == 0) {
                    if (temp.getDim() == 1) {
                        if (node.getPair().getLine() == 73) {
                            int flag = 1;
                        }
                        //Pairs result = new Pairs(temp.getKind(), temp.getToken(), temp.getType(), temp.getLine(), dim);
                        //ArrayList<Pairs> list = new ArrayList<>();
                        //list.add(calculation.pop());
                        // result.setParams(list);
                        // calculation.push(result);
                    } else {
                        Expression expression = new Expression(calculation.pop(), calculation.pop(), Quaternion.OP.ADD);
                        expression.solveAnswer(index);
                        index++;
                        IRs.add(expression);
                        //pairs.getParams().clear();
                        //pairs.getParams().add(expression.getAnswer());
                        list.add(expression.getAnswer());
                        //calculation.push(expression.getAnswer());
                    }
                }
            } else if (j.getPair().getKind().equals(Pairs.Kind.LBRACK)) {
                //pairs.setDim(pairs.getDim() - 1);
                dim--;
            }
        }
        if (array == 0) {
            calculation.push(pairs);
        } else {
            Pairs result = new Pairs(temp.getKind(), temp.getToken(), temp.getType(), temp.getLine(), dim);
            if (list.isEmpty()) {
                list.add(calculation.pop());
            }
            result.setParams(list);
            if (result.getKind().equals(Pairs.Kind.ARRAY_VAR) || result.getKind().equals(Pairs.Kind.ARRAY_VAL)) {
                Pairs tempA = containsIdent(result.getToken());
                if (!tempA.values.isEmpty()) {
                    if (result.getParams().get(0).getValue() < tempA.values.size() && result.getParams().get(0).getValue() >= 0)
                    result.setValue(tempA.values.get(result.getParams().get(0).getValue()));
                }
                calculation.push(result);
            } else {
                calculation.push(result);
            }
        }
        if (node.getPair().getLine() == 73) {
            int flag = 1;
        }
        return pairs;
    }

    public void buildTableStmt(Node node) {
        Pairs first = node.getChildren().get(0).getPair();
        if (first.getLine() == 67) {
            int flag = 1;
        }
        Pairs address = null;
        Pairs address2 = null;
        if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("LVal")) {
            Pairs temp = null;
            if (node.getChildren().size() > 2 && node.getChildren().get(1).getPair().getKind().equals(Pairs.Kind.ASSIGN)) {
                processLVal(node.getChildren().get(0));
                temp = calculation.pop();
                if (temp.getKind().equals(Pairs.Kind.ARRAY_VAL) || temp.getKind().equals(Pairs.Kind.ARRAY_VAR)) {
                    address = temp.getParams().get(0);
                    if (address.getToken().contains("&")) {
                        map.put(address.getToken(), true);
                    }
                }
            }
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Exp")) {
                    buildTableExp(i);
                    Pairs answer = calculation.pop();
                    if (answer.getKind().equals(Pairs.Kind.ARRAY_VAL) || answer.getKind().equals(Pairs.Kind.ARRAY_VAR)) {
                        if (!answer.getParams().isEmpty()) {
                            address2 = answer.getParams().get(0);
                        }
                        Assign assign = new Assign(temp, address, answer, address2);
                        IRs.add(assign);
                    } else if (answer.getKind().equals(Pairs.Kind.FUNC)) {
                        Pairs ret = new Pairs(Pairs.Kind.RET, "RET");
                        Assign assign = new Assign(temp, address, ret);
                        IRs.add(assign);
                    } else {
                        Assign assign = new Assign(temp, address, answer);
                        IRs.add(assign);
                        if (address == null) {
                            /*if (answer.getInit()) {
                                temp.setValue(answer.getValue());
                            }*/
                        }
                    }
                } else if (i.getPair().getKind().equals(Pairs.Kind.GETINTTK)) {
                    if (temp.getKind().equals(Pairs.Kind.ARRAY_VAL) || temp.getKind().equals(Pairs.Kind.ARRAY_VAR)) {
                        Assign assign = new Assign(temp, temp.getParams().get(0), i.getPair(), Quaternion.OP.GETINT);
                        temp.setInit(false);
                        IRs.add(assign);
                    } else {
                        Assign assign = new Assign(temp, null, i.getPair(), Quaternion.OP.GETINT);
                        temp.setInit(false);
                        IRs.add(assign);
                    }
                }
            }
        } else if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("Exp")) {
            buildTableExp(node.getChildren().get(0));
        } else if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("Block")) {
            buildIR(node);
        } else if (first.getKind().equals(Pairs.Kind.WHILETK)) {
            int index = while_index;
            while_index++;
            isWhile = true;
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Stmt")) {
                    Label label = new Label("begin", index, "while");
                    IRs.add(label);
                    if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.PARSE) && i.getChildren().get(0).getPair().getToken().equals("Block")) {
                        SymbolTable table = new SymbolTable();
                        table.setType("circle");
                        int indexBlock = block_index;
                        block_index++;
                        Label label1 = new Label("begin", indexBlock, "block");
                        IRs.add(label1);
                        tables.push(table);
                        table.setWhileIndex(index);
                        buildIR(i.getChildren().get(0));
                        //buildTableStmt(i);
                        tables.pop();
                        Label label2 = new Label("end", indexBlock, "block");
                        IRs.add(label2);
                    } else if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.BREAKTK) || i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.CONTINUETK)) {
                        if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.BREAKTK)) {
                            BranchJump go = new BranchJump(Quaternion.OP.GOTO, "end", index, "while");
                            IRs.add(go);
                        } else {
                            BranchJump go = new BranchJump(Quaternion.OP.GOTO, "begin", index, "w_cond");
                            IRs.add(go);
                        }
                    } else {
                        buildTableStmt(i);
                    }
                } else if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Cond")) {
                    Label label = new Label("begin", index, "w_cond");
                    IRs.add(label);
                    buildTableExp(i.getChildren().get(0));
                    Label label1 = new Label("end", index, "w_cond");
                    IRs.add(label1);
                    isWhile = false;
                } else {
                    buildIR(i);
                }
            }
            BranchJump jump = new BranchJump(Quaternion.OP.GOTO, "begin", index, "w_cond");
            IRs.add(jump);
            Label label = new Label("end", index, "while");
            IRs.add(label);
        } else if (first.getKind().equals(Pairs.Kind.BREAKTK) || first.getKind().equals(Pairs.Kind.CONTINUETK)) {
            if (first.getKind().equals(Pairs.Kind.BREAKTK)) {
                BranchJump go = new BranchJump(Quaternion.OP.GOTO, "end", tables.peek().getWhileIndex(), "while");
                IRs.add(go);
            } else {
                BranchJump go = new BranchJump(Quaternion.OP.GOTO, "begin", tables.peek().getWhileIndex(), "w_cond");
                IRs.add(go);
            }
        } else if (first.getKind().equals(Pairs.Kind.RETURNTK)) {
            if (node.getChildren().size() > 2) {
                buildTableExp(node.getChildren().get(1));
                if (calculation.peek().getKind().equals(Pairs.Kind.ARRAY_VAL) || calculation.peek().getKind().equals(Pairs.Kind.ARRAY_VAR)) {
                    Pairs temp = new Pairs(Pairs.Kind.VAL, useMap());
                    Pairs array = calculation.pop();
                    Assign assign = new Assign(temp, null, array, array.getParams().get(0));
                    IRs.add(assign);
                    FuncCallRet funcCallRet = new FuncCallRet(temp, null, null, Quaternion.OP.RET);
                    IRs.add(funcCallRet);
                } else {
                    FuncCallRet funcCallRet = new FuncCallRet(calculation.pop(), null, null, Quaternion.OP.RET);
                    IRs.add(funcCallRet);
                }
            } else {
                FuncCallRet funcCallRet = new FuncCallRet(null, null, null, Quaternion.OP.RET);
                IRs.add(funcCallRet);
            }
        } else if (first.getKind().equals(Pairs.Kind.PRINTFTK)) {
            int cnt1 = 0;
            int cnt2 = 0;
            int flag = 0;
            if (first.getLine() == 723) {
                flag = 0;
            }
            ArrayList<Pairs> exps = new ArrayList<>();
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Exp")) {
                    cnt2++;
                    buildTableExp(i);
                    exps.add(calculation.pop());
                    /*Pairs ret = new Pairs(Pairs.Kind.RET, "RET");
                    Assign assign = new Assign(, null, ret);
                    IRs.add(assign);*/
                }
            }
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.STRCON)) {
                    String str = i.getPair().getToken();
                    String temp = "";
                    for (int j = 1; j < str.length() - 1; j++) {
                        if (str.charAt(j) == '%') {
                            if (j != str.length() - 1 && str.charAt(j + 1) == 'd') {
                                if (temp.length() != 0) {
                                    String string = temp;
                                    PrintOut print = new PrintOut(string);
                                    IRs.add(print);
                                    temp = "";
                                }
                                if (exps.get(cnt1).getKind().equals(Pairs.Kind.ARRAY_VAL) || exps.get(cnt1).getKind().equals(Pairs.Kind.ARRAY_VAR)) {
                                    PrintOut print = new PrintOut(exps.get(cnt1), exps.get(cnt1).getParams().get(0));
                                    IRs.add(print);
                                } else {
                                    PrintOut print = new PrintOut(exps.get(cnt1));
                                    IRs.add(print);
                                }
                                cnt1++;
                                j++;
                            }
                        } else if (str.charAt(j) == 32 || str.charAt(j) == 33 || (str.charAt(j) >= 40 && str.charAt(j) <= 126)) {
                            if (str.charAt(j) == '\\') {
                                if (j != str.length() - 1 && str.charAt(j + 1) == 'n') {
                                    temp = temp + "\\n";
                                    //PrintOut print = new PrintOut("\\n");
                                    //IRs.add(print);
                                    j++;
                                }
                            } else {
                                /*String string = "";
                                string = string + str.charAt(j);
                                PrintOut print = new PrintOut(string);
                                IRs.add(print);*/
                                temp = temp + str.charAt(j);
                            }
                        }
                    }
                    if (temp.length() != 0) {
                        String string = temp;
                        PrintOut print = new PrintOut(string);
                        IRs.add(print);
                    }
                }
            }
        } else if (first.getKind().equals(Pairs.Kind.IFTK)) {
            int hasElse = 0;
            isIF = true;
            int index = branch_index;
            branch_index++;
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Cond")) {
                    Label label = new Label("begin", index, "cond");
                    IRs.add(label);
                    buildTableExp(i.getChildren().get(0));
                    isIF = false;
                    Label label1 = new Label("end", index, "cond");
                    IRs.add(label1);
                } else if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("Stmt")) {
                    Label label = new Label("begin", index, "if");
                    IRs.add(label);
                    buildTableStmt(i);
                } else if (i.getPair().getKind().equals(Pairs.Kind.ELSETK)) {
                    BranchJump jump = new BranchJump(Quaternion.OP.GOTO, "endAll", index, "if");
                    IRs.add(jump);
                    hasElse = 1;
                    Label label = new Label("end", index, "if");
                    IRs.add(label);
                    buildTableStmt(node.getChildren().get(node.getChildren().size() - 1));
                    Label label1 = new Label("endAll", index, "if");
                    IRs.add(label1);
                    break;
                }
            }
            if (hasElse == 0) {
                Label label = new Label("end", index, "if");
                IRs.add(label);
            }
        } else {
            buildIR(node);
        }
    }

    public Pairs buildTableUnaryExp(Node node) {
        Pairs first = node.getChildren().get(0).getPair();
        if (first.getLine() == 529) {
            int flag = 1;
        }
        if (first.getKind().equals(Pairs.Kind.IDENFR)) {
            Pairs pairs = containsIdent(first.getToken());
            if (first.getLine() == 67) {
                int flag = 1;
            }
            for (Node i : node.getChildren()) {
                if (i.getPair().getKind().equals(Pairs.Kind.PARSE) && i.getPair().getToken().equals("FuncRParams")) {
                    ArrayList<Quaternion> tempIRs = new ArrayList<>();
                    for (Node j : i.getChildren()) {
                        if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Exp")) {
                            buildTableExp(j);
                            Pairs result = calculation.pop();
                            Pairs address = null;
                            /*if (result.getParams().size() != 0) {
                                if (result.getParams().size() == 2) {
                                    address = null;
                                } else {
                                    address = result.getParams().get(0);
                                }
                            }*/
                            int dim;
                            if (containsIdent(result.getToken()) == null) {
                                dim = 0;
                            } else {
                                dim = containsIdent(result.getToken()).getDim();
                            }
                            if (result.getDim() == 1) {
                                if (dim == 2) {
                                    address = result.getParams().get(0);
                                }
                            } else if (result.getDim() == 0) {
                                if (dim != 0) {
                                    address = result.getParams().get(0);
                                }
                            }
                            FuncCallRet push = new FuncCallRet(result, pairs, address, Quaternion.OP.PUSH);
                            //IRs.add(push);
                            tempIRs.add(push);
                        }
                    }
                    IRs.addAll(tempIRs);
                    if (first.getLine() == 529) {
                        int flag = 1;
                    }
                } else if (i.getPair().getKind().equals(Pairs.Kind.LPARENT)) {
                    calculation.push(i.getPair());
                } else if (i.getPair().getKind().equals(Pairs.Kind.RPARENT)) {
                    calculation.pop();
                }
            }
            FuncCallRet call = new FuncCallRet(null, pairs, null, Quaternion.OP.CALL);
            IRs.add(call);
            if (pairs.getType().equals("int")) {
                Pairs ret = new Pairs(Pairs.Kind.RET, "RET");
                Pairs temp = new Pairs(Pairs.Kind.VAL, useMap());
                Assign assign = new Assign(temp, null, ret);
                IRs.add(assign);
                calculation.push(temp);
            }
            return new Pairs(pairs.getKind(), pairs.getToken(), pairs.getType(), pairs.getDim());
        } else if (first.getKind().equals(Pairs.Kind.PARSE) && first.getToken().equals("UnaryOp")) {
            Node unaryop = node.getChildren().get(0).getChildren().get(0);
            buildTableExp(node.getChildren().get(1));
            if (unaryop.getPair().getKind().equals(Pairs.Kind.MINU)) {
                Pairs zero = new Pairs(Pairs.Kind.NUM, "0");
                zero.setValue(0);
                if (calculation.peek().getKind().equals(Pairs.Kind.NUM)) {
                    String old = calculation.peek().getToken();
                    if (old.contains("-")) {
                        calculation.peek().setToken(old.split("-")[1]);
                    } else {
                        calculation.peek().setToken("-" + old);
                    }
                    calculation.peek().setValue(-calculation.peek().getValue());
                } else {
                    Expression expression = new Expression(zero, calculation.pop(), Quaternion.OP.SUB);
                    expression.solveAnswer(index);
                    index++;
                    calculation.push(expression.getAnswer());
                    IRs.add(expression);
                }
            } else if (unaryop.getPair().getKind().equals(Pairs.Kind.NOT)) {
                Pairs one = new Pairs(Pairs.Kind.NUM, "1");
                one.setValue(1);
                Expression expression = new Expression(calculation.pop(), one, Quaternion.OP.SLTIU);
                expression.solveAnswer(index);
                index++;
                calculation.push(expression.getAnswer());
                IRs.add(expression);
            }
            return null;
        } else {
            return buildTableExp(node.getChildren().get(0));
        }
    }

    public Pairs buildTableExp(Node i) {
        if (i.getPair().getToken().equals("Exp")) {
            return buildTableExp(i.getChildren().get(0));
        } else if (i.getPair().getToken().equals("PrimaryExp")) {
            if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.LPARENT)) {
                calculation.push(i.getChildren().get(0).getPair());
                buildTableExp(i.getChildren().get(1));
                Pairs temp = calculation.pop();
                calculation.pop();
                calculation.push(temp);
                return null;
            } else if (i.getChildren().get(0).getPair().getKind().equals(Pairs.Kind.PARSE) && i.getChildren().get(0).getPair().getToken().equals("LVal")) {
                processLVal(i.getChildren().get(0));
                if (i.getChildren().get(0).getPair().getLine() == 154) {
                    int flag = 1;
                }
                /*Pairs pairs = null;
                //Pairs pairs = new Pairs(Pairs.Kind.VAR, node.getChildren().get(0).getPair().getToken(), "int", node.getChildren().get(0).getPair().getLine());
                Pairs result = new Pairs(Pairs.Kind.VAL, i.getPair().getToken());
                for (Node j : i.getChildren().get(0).getChildren()) {
                    if (j.getPair().getKind().equals(Pairs.Kind.IDENFR)) {
                        // pairs = containsIdent(j.getPair().getToken());
                        if (pairs == null) {

                            break;
                        } else {
                            result = new Pairs(pairs.getKind(), pairs.getToken(), pairs.getType(), pairs.getLine(), pairs.getDim());

                        }
                    } else if (j.getPair().getKind().equals(Pairs.Kind.PARSE) && j.getPair().getToken().equals("Exp")) {
                        if (result.getDim() == 2) {
                            result.setDim(result.getDim() - 1);
                        } else if (result.getDim() == 1) {
                            result.setDim(result.getDim() - 1);
                            result.setKind(Pairs.Kind.VAL);
                        }
                        buildTableExp(j);
                    }
                }*/
                return null;
            } else {
                return buildTableExp(i.getChildren().get(0));
            }
        } else if (i.getPair().getToken().equals("UnaryExp")) {
            if (i.getPair().getLine() == 1) {
                int flag = 1;
            }
            return buildTableUnaryExp(i);
        } else if (i.getPair().getToken().equals("Number")) {
            Pairs pairs = new Pairs(Pairs.Kind.NUM, i.getChildren().get(0).getPair().getToken(), "int", i.getPair().getLine(), 0);
            pairs.setValue(Integer.parseInt(i.getChildren().get(0).getPair().getToken()));
            calculation.push(pairs);
            return null;//pairs;
        } else if (i.getPair().getToken().equals("MulExp")) {
            if (i.getPair().getLine() == 92) {
                int flag = 1;
            }
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    if (j.getPair().getKind().equals(Pairs.Kind.MULT)) {
                        calculation.push(j.getPair());
                    } else if (j.getPair().getKind().equals(Pairs.Kind.MOD)) {
                        calculation.push(j.getPair());
                    } else if (j.getPair().getKind().equals(Pairs.Kind.DIV)) {
                        calculation.push(j.getPair());
                    } else if (j.getPair().getToken().equals("UnaryExp")) {
                        buildTableExp(j);
                        Pairs pair_a = calculation.pop();
                        if (!calculation.isEmpty() && (calculation.peek().getKind().equals(Pairs.Kind.MULT) || calculation.peek().getKind().equals(Pairs.Kind.MOD) || calculation.peek().getKind().equals(Pairs.Kind.DIV))) {
                            Quaternion.OP op = kindToOp(calculation.pop().getKind());
                            Expression expression = new Expression(calculation.pop(), pair_a, op);
                            if (j.getPair().getLine() == 93) {
                                int flag = 1;
                            }
                            expression.solveAnswer(index);
                            index++;
                            IRs.add(expression);
                            calculation.push(expression.getAnswer());
                        } else {
                            calculation.push(pair_a);
                        }
                    }
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("AddExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    if (j.getPair().getLine() == 197) {
                        int flag = 1;
                    }
                    if (j.getPair().getKind().equals(Pairs.Kind.PLUS)) {
                        calculation.push(j.getPair());
                    } else if (j.getPair().getKind().equals(Pairs.Kind.MINU)) {
                        calculation.push(j.getPair());
                    } else if (j.getPair().getToken().equals("MulExp")) {
                        buildTableExp(j);
                        Pairs pair_a = calculation.pop();
                        if (!calculation.isEmpty() && (calculation.peek().getKind().equals(Pairs.Kind.PLUS) || calculation.peek().getKind().equals(Pairs.Kind.MINU))) {
                            Quaternion.OP op = kindToOp(calculation.pop().getKind());
                            Expression expression = new Expression(calculation.pop(), pair_a, op);
                            expression.solveAnswer(index);
                            index++;
                            IRs.add(expression);
                            calculation.push(expression.getAnswer());
                            //return expression.getAnswer();
                        } else {
                            calculation.push(pair_a);
                        }
                    }
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("RelExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                return buildTableExp(i.getChildren().get(0));
            } else {
                for (Node j : i.getChildren()) {
                    if (noBranch == false) {
                        buildTableExp(j);
                    } else {
                        if (j.getPair().getKind().equals(Pairs.Kind.LSS) || j.getPair().getKind().equals(Pairs.Kind.LEQ)
                                || j.getPair().getKind().equals(Pairs.Kind.GRE) || j.getPair().getKind().equals(Pairs.Kind.GEQ)) {
                            calculation.push(j.getPair());
                        } else if (j.getPair().getToken().equals("AddExp")) {
                            buildTableExp(j);
                            Pairs pair_b = calculation.pop();
                            if (!calculation.isEmpty() && (calculation.peek().getKind().equals(Pairs.Kind.LSS) || calculation.peek().getKind().equals(Pairs.Kind.LEQ)
                                    || calculation.peek().getKind().equals(Pairs.Kind.GRE) || calculation.peek().getKind().equals(Pairs.Kind.GEQ))) {
                                //Quaternion.OP op = kindToOp(calculation.pop().getKind());
                                Pairs op = calculation.pop();
                                Pairs pair_a = calculation.pop();
                                Pairs zero = new Pairs(Pairs.Kind.NUM, "0", "int", i.getPair().getLine(), 0);
                                zero.setValue(0);
                                Pairs one = new Pairs(Pairs.Kind.NUM, "1", "int", i.getPair().getLine(), 0);
                                one.setValue(1);
                                if (op.getKind().equals(Pairs.Kind.LSS)) {
                                    Expression expression = new Expression(pair_a, pair_b, Quaternion.OP.SLT);
                                    expression.solveAnswer(index);
                                    index++;
                                    calculation.add(expression.getAnswer());
                                    IRs.add(expression);
                                } else if (op.getKind().equals(Pairs.Kind.LEQ)) {
                                    Expression expression = new Expression(pair_b, pair_a, Quaternion.OP.SLT);
                                    expression.solveAnswer(index);
                                    index++;
                                    Expression expression1 = new Expression(one, expression.getAnswer(), Quaternion.OP.SUB);
                                    expression1.solveAnswer(index);
                                    index++;
                                    calculation.add(expression1.getAnswer());
                                    IRs.add(expression);
                                    IRs.add(expression1);
                                } else if (op.getKind().equals(Pairs.Kind.GRE)) {
                                    Expression expression = new Expression(pair_b, pair_a, Quaternion.OP.SLT);
                                    expression.solveAnswer(index);
                                    index++;
                                    calculation.add(expression.getAnswer());
                                    IRs.add(expression);
                                } else if (op.getKind().equals(Pairs.Kind.GEQ)) {
                                    Expression expression = new Expression(pair_a, pair_b, Quaternion.OP.SLT);
                                    expression.solveAnswer(index);
                                    index++;
                                    Expression expression1 = new Expression(one, expression.getAnswer(), Quaternion.OP.SUB);
                                    expression1.solveAnswer(index);
                                    index++;
                                    calculation.add(expression1.getAnswer());
                                    IRs.add(expression);
                                    IRs.add(expression1);
                                }
                                //return expression.getAnswer();
                            } else {
                                calculation.push(pair_b);
                            }
                        }
                    }
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("EqExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                buildTableExp(i.getChildren().get(0));
                Pairs zero = new Pairs(Pairs.Kind.NUM, "0", "int", i.getPair().getLine(), 0);
                zero.setValue(0);
                /*Cmp cmp = new Cmp(calculation.pop(), zero);
                if (isIF) {
                    BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", branch_index - 1, "if");
                    branches.push(cmp);
                    cmp.setJump(jump);
                    //IRs.add(jump);
                } else if (isWhile) {
                    BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", while_index - 1, "while");
                    branches.push(cmp);
                    cmp.setJump(jump);
                }*/
                return null;
            } else {
                for (Node j : i.getChildren()) {
                    if (noBranch == false) {
                        buildTableExp(j);
                    } else {
                        if (j.getPair().getKind().equals(Pairs.Kind.EQL) || j.getPair().getKind().equals(Pairs.Kind.NEQ)) {
                            calculation.push(j.getPair());
                        } else if (j.getPair().getToken().equals("RelExp")) {
                            buildTableExp(j);
                            Pairs pair_b = calculation.pop();
                            if (!calculation.isEmpty() && (calculation.peek().getKind().equals(Pairs.Kind.EQL) || calculation.peek().getKind().equals(Pairs.Kind.NEQ))) {
                                Pairs op = calculation.pop();
                                Pairs pair_a = calculation.pop();
                                /*Pairs zero = new Pairs(Pairs.Kind.VAL, "0", "int", i.getPair().getLine(), 0);
                                zero.setValue(0);*/
                                Pairs zero = new Pairs(Pairs.Kind.NUM, "0", "int", i.getPair().getLine(), 0);
                                zero.setValue(0);
                                Pairs one = new Pairs(Pairs.Kind.NUM, "1", "int", i.getPair().getLine(), 0);
                                one.setValue(1);
                                if (op.getKind().equals(Pairs.Kind.EQL)) {
                                    Expression expression = new Expression(pair_a, pair_b, Quaternion.OP.XOR);
                                    expression.solveAnswer(index);
                                    index++;
                                    Expression expression1 = new Expression(expression.getAnswer(), one,Quaternion.OP.SLTIU);
                                    expression1.solveAnswer(index);
                                    index++;
                                    calculation.add(expression1.getAnswer());
                                    IRs.add(expression);
                                    IRs.add(expression1);
                                } else {
                                    Expression expression = new Expression(pair_a, pair_b, Quaternion.OP.XOR);
                                    expression.solveAnswer(index);
                                    index++;
                                    Expression expression1 = new Expression(expression.getAnswer(), one,Quaternion.OP.SLTIU);
                                    expression1.solveAnswer(index);
                                    index++;
                                    Expression expression2 = new Expression(one,expression1.getAnswer(),Quaternion.OP.SUB);
                                    expression2.solveAnswer(index);
                                    index++;
                                    calculation.add(expression2.getAnswer());
                                    //calculation.add(expression.getAnswer());
                                    IRs.add(expression);
                                    IRs.add(expression1);
                                    IRs.add(expression2);
                                }
                                /*Cmp cmp = new Cmp(pair_a, pair_b);
                                if (isIF) {
                                    if (op.getKind().equals(Pairs.Kind.EQL)) {
                                        BranchJump jump = new BranchJump(Quaternion.OP.BNE, "end", branch_index - 1, "if");
                                        cmp.setJump(jump);
                                    } else {
                                        BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", branch_index - 1, "if");
                                        cmp.setJump(jump);
                                    }
                                } else if (isWhile) {
                                    if (op.getKind().equals(Pairs.Kind.EQL)) {
                                        BranchJump jump = new BranchJump(Quaternion.OP.BNE, "end", while_index - 1, "while");
                                        cmp.setJump(jump);
                                    } else {
                                        BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", while_index - 1, "while");
                                        cmp.setJump(jump);
                                    }
                                }
                                branches.push(cmp);*/
                                //return expression.getAnswer();
                            } else {
                                calculation.push(pair_b);
                            }
                        }
                    }
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("LAndExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                Node j = i.getChildren().get(0);
                buildTableExp(i.getChildren().get(0));
                Pairs one = new Pairs(Pairs.Kind.NUM, "1", "int", i.getPair().getLine(), 0);
                one.setValue(1);
                Pairs zero = new Pairs(Pairs.Kind.NUM, "0", "int", i.getPair().getLine(), 0);
                zero.setValue(0);
                Pairs pair_a = calculation.pop();
                Cmp cmp = new Cmp(pair_a, zero);
                if (isIF) {
                    BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", branch_index - 1, "if");
                    cmp.setJump(jump);
                } else if (isWhile) {
                    BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", while_index - 1, "while");
                    cmp.setJump(jump);
                }
                branches.push(cmp);
                IRs.add(cmp);
                return null;
            } else {
                for (Node j : i.getChildren()) {
                    if (noBranch == false) {
                        buildTableExp(j);
                    } else {
                        if (j.getPair().getKind().equals(Pairs.Kind.AND)) {
                            //calculation.push(j.getPair());
                            isAnd = true;
                        } else if (j.getPair().getToken().equals("EqExp")) {
                            buildTableExp(j);
                            // Pairs pair_a = calculation.pop();
                            // Cmp cmp = (Cmp) branches.pop();
                            Pairs one = new Pairs(Pairs.Kind.NUM, "1", "int", i.getPair().getLine(), 0);
                            one.setValue(1);
                            Pairs zero = new Pairs(Pairs.Kind.NUM, "0", "int", i.getPair().getLine(), 0);
                            zero.setValue(0);
                            Pairs pair_a = calculation.pop();
                            Cmp cmp = new Cmp(pair_a, zero);
                            if (isIF) {
                                BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", branch_index - 1, "if");
                                cmp.setJump(jump);
                            } else if (isWhile) {
                                BranchJump jump = new BranchJump(Quaternion.OP.BEQ, "end", while_index - 1, "while");
                                cmp.setJump(jump);
                            }
                            branches.push(cmp);
                            if (i.getChildren().indexOf(j) == i.getChildren().size() - 1) {
                                // cmp.getJump().reversal();
                                int flag = 1;
                            } else {

                            }
                            IRs.add(cmp);
                        }
                    }
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("LOrExp")) {
            if (i.getChildren() == null) {
                return null;
            }
            if (i.getChildren().size() == 1) {
                buildTableExp(i.getChildren().get(0));
                //Cmp cmp = new Cmp()
                Node j = i.getChildren().get(0);
                if (!branches.isEmpty()) {
                    branches.clear();
                    /*Cmp cmp = (Cmp) branches.pop();
                    if (i.getChildren().indexOf(j) == i.getChildren().size() - 1) {

                    } else {
                        int flag = 1;
                        cmp.getJump().reversal();
                    }*/
                   // IRs.add(cmp);
                }
                return null;
            } else {
                int cond_index = 1;
                for (Node j : i.getChildren()) {
                    if (noBranch == false) {
                        buildTableExp(j);
                    } else {
                        if (j.getPair().getKind().equals(Pairs.Kind.OR)) {
                            //calculation.push(j.getPair());
                            if (isWhile) {
                                Label label = new Label("begin", while_index -1,"while");
                                label.setCond_index(cond_index);
                                IRs.add(label);
                            } else if (isIF) {
                                Label label = new Label("begin", branch_index -1,"if");
                                label.setCond_index(cond_index);
                                IRs.add(label);
                            }
                            cond_index++;
                        } else if (j.getPair().getToken().equals("LAndExp")) {
                            buildTableExp(j);
                            if (!branches.isEmpty()) {
                                //Cmp cmp = (Cmp) branches.pop();
                                for (Quaternion k : branches) {
                                    if (i.getChildren().indexOf(j) == i.getChildren().size() - 1) {

                                    } else {
                                        if (branches.indexOf(k) == branches.size() - 1) {
                                            ((Cmp) k).getJump().reversal();
                                        } else {
                                            ((Cmp) k).getJump().toNextCond(cond_index);
                                        }
                                    }
                                }
                                branches.clear();
                                /*if (i.getChildren().indexOf(j) == i.getChildren().size() - 1) {

                                } else {
                                    cmp.getJump().reversal();
                                }*/
                            }
                        }
                    }
                }
                return new Pairs(Pairs.Kind.VAL, "number", "int", i.getPair().getLine(), 0);
            }
        } else if (i.getPair().getToken().equals("ConstExp")) {
            return buildTableExp(i.getChildren().get(0));
        }
        return null;

    }
}
